<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="../src/css/default.css">
    <title>弹球屏保案例</title>
    <style>
        body {
            background-color: #000;
        }

        /* 边界 */
        .box {
            position: relative;
            width: 800px;
            height: 800px;
            margin: 10px auto 0;
            border: 16px groove purple;
        }

        /* 运动小球 */
        .box>div {
            position: absolute;
            width: 94px;
            height: 94px;
            background-color: goldenrod;
            font-size: 2em;
            color: black;
            line-height: 94px;
            text-align: center;
            border: 6px solid brown;
            border-radius: 50%;
        }
    </style>
</head>

<body>

    <div class="box">
        <!-- <div class="ball">1</div>
        <div class="ball2">2</div> -->
    </div>

    <script>
        /* 面向过程思路 如果想实现多个小球动画 将会非常麻烦 */
        /*  
            let ball = document.querySelector('.ball')

            // 小球的偏移量
            let x = 0
            let y = 0
            // 小球的移动速度和方向 默认正方向 负数则表示反向移动
            let vx = 2
            let vy = 3

            // 运动模型
            setInterval(() => {

                // 边界判断
                if (x >= 700 || x < 0) {
                    // 等价于 vx = -vx 但是改为 *= -1 就可以用来 实现速度衰减
                    vx *= -1
                }
                if (y >= 700 || y < 0) vy *= -1


                // 修改盒子的位置
                x += vx
                y += vy
                ball.style.transform = `translate(${x}px, ${y}px)`
            }, 1000 / 60)
        */
    </script>

    <!-- 
        我们能控制什么？
            现在是一个小球，如何再加一个？
            需要将上述代码复制一遍，再添加一个ball；
            
            但是这样就会声明很多全局变量，而且有大量重复的代码，影响性能；

        怎么修改？
            利用对象 面向对象的思想去解决这个问题；
            即： 将事件状态交给 应该管理它的 对象 去处理
                而不是把所有状态都交给 window处理； 
     -->

    <script>
        let box = document.querySelector('.box')
        /* 
            面向对象思想 能使得上述问题得到 优化
                大大减少了全局变量 降低了资源消耗
        */

        /* 在全局去抽象出两个公用方法 */

        // 更新小球位置
        function updateLocation() {
            // 边界判断
            if (this.x >= 700 || this.x < 0) this.vx *= -1
            if (this.y >= 700 || this.y < 0) this.vy *= -1
            // 偏移量 this.x
            this.x += this.vx
            this.y += this.vy

            // 垂直方向自由落体的效果
            // this.vy += 0.3
        }

        // 渲染小球
        function renderBall() {
            this.el.style.transform = `translate(${this.x}px, ${this.y}px)`
        }

        // 小球对象 是一个抽象的对象
        // 包含 哪个小球 小球的偏移量 小球的速度等属性
        // 然后抽象出 小球的运动方法

        /*
            let ball = {
                el: document.querySelector('.ball'),
                x: 0,
                y: 0,
                vx: 2,
                vy: 3,
                update: updateLocation,
                render: renderBall
            }
        */
        // 这时候 再去创建一个小球 就会变得很方便
        /*    
            let ball2 = {
                el: document.querySelector('.ball2'),
                x: 0,
                y: 0,
                vx: 3,
                vy: 2,
                update: updateLocation,
                render: renderBall
            }
        */
        // 但是 如果一次性要生成 10个 小球呢？
        // 上面的方法还是很麻烦
        // 此时 可以写一个函数 专门来创建小球

        function createBalls() {
            // 创建 div
            let ball = document.createElement('div')
            box.appendChild(ball) // 添加到盒子里去

            return {
                el: ball,
                x: 0,
                y: 0,
                // 随机生成偏移量
                vx: 10 * Math.random() - 5,
                vy: 10 * Math.random() - 4,
                update: updateLocation,
                render: renderBall
            }

        }
        // 用来保存生成的小球
        let ballList = []

        for (let i = 0; i < 10; i++) {
            ballList.push(createBalls())
            ballList[i].el.innerHTML = i + 1 // 编个号
        }

        // 运动模型
        setInterval(() => {
            // 更新状态
            // ball.update()
            // ball2.update()

            // 渲染
            // ball.render()
            // ball2.render()

            // 让每一个小球都去各自运动
            ballList.forEach(ball => {
                ball.update()
                ball.render()
            })

        }, 1000 / 60)
    </script>

</body>

</html>